// webgl/webgl_multiple_elements.js
import {document,window,requestAnimationFrame,cancelAnimationFrame,Event,core,performance} from 'dhtml-weixin';
import * as THREE from '../three/Three.js';
import  { OrbitControls } from './jsm/controls/OrbitControls.js';

var requestId
Page({
	   
         onUnload() {
	   		cancelAnimationFrame(requestId, this.canvas)
this.worker && this.worker.terminate()
		setTimeout(() => {
			if (this.renderer instanceof THREE.WebGLRenderer) {
				this.renderer.dispose()
				this.renderer.forceContextLoss()
				this.renderer.context = null
				this.renderer.domElement = null
				this.renderer = null
			}
		}, 0)
        
	},
         webgl_touch(e) {
        const web_e = Event.fix(e)
        //window.dispatchEvent(web_e)
        //document.dispatchEvent(web_e)
        this.canvas.dispatchEvent(web_e)
    },
async onLoad() {
    var canvas
        const canvas3d = this.canvas =await document.createElementAsync("canvas","webgl")
var that = this
        
			let  renderer;

			const scenes = [];

		await	init();
			animate();

		async	function init() {

				canvas = await document.getElementByIdAsync( 'c' );

				const geometries = [
					new THREE.BoxGeometry( 1, 1, 1 ),
					new THREE.SphereGeometry( 0.5, 12, 8 ),
					new THREE.DodecahedronGeometry( 0.5 ),
					new THREE.CylinderGeometry( 0.5, 0.5, 1, 12 )
				];

				const content = document.getElementById( 'content' );

				for ( let i = 0; i < 40; i ++ ) {

					const scene = new THREE.Scene();

					// make a list item
					const element = document.createElement( 'div' );
					element.className = 'list-item';

					const sceneElement = document.createElement( 'div' );
					element.appendChild( sceneElement );

					const descriptionElement = document.createElement( 'div' );
					descriptionElement.innerText = 'Scene ' + ( i + 1 );
					element.appendChild( descriptionElement );

					// the element that represents the area we want to render the scene
					scene.userData.element = sceneElement;
					content.appendChild( element );

					const camera = new THREE.PerspectiveCamera( 50, 1, 1, 10 );
					camera.position.z = 2;
					scene.userData.camera = camera;

					const controls = new OrbitControls( scene.userData.camera, scene.userData.element );
					controls.minDistance = 2;
					controls.maxDistance = 5;
					controls.enablePan = false;
					controls.enableZoom = false;
					scene.userData.controls = controls;

					// add one random mesh to each scene
					const geometry = geometries[ geometries.length * Math.random() | 0 ];

					const material = new THREE.MeshStandardMaterial( {

						color: new THREE.Color().setHSL( Math.random(), 1, 0.75 ),
						roughness: 0.5,
						metalness: 0,
						flatShading: true

					} );

					scene.add( new THREE.Mesh( geometry, material ) );

					scene.add( new THREE.HemisphereLight( 0xaaaaaa, 0x444444 ) );

					const light = new THREE.DirectionalLight( 0xffffff, 0.5 );
					light.position.set( 1, 1, 1 );
					scene.add( light );

					scenes.push( scene );

				}


				renderer = that.renderer = new THREE.WebGLRenderer( { canvas:canvas3d,antialias: true } );
				renderer.setClearColor( 0xffffff, 1 );
				renderer.setPixelRatio( window.devicePixelRatio );

			}

			function updateSize() {

				const width = canvas.clientWidth;
				const height = canvas.clientHeight;

				if ( canvas.width !== width || canvas.height !== height ) {

					renderer.setSize( width, height, false );

				}

			}

			function animate() {

				render();
				requestAnimationFrame(animate);

			}

			function render() {

				updateSize();

				canvas.style.transform = `translateY(${window.scrollY}px)`;

				renderer.setClearColor( 0xffffff );
				renderer.setScissorTest( false );
				renderer.clear();

				renderer.setClearColor( 0xe0e0e0 );
				renderer.setScissorTest( true );

				scenes.forEach( function ( scene ) {

					// so something moves
					scene.children[ 0 ].rotation.y = Date.now() * 0.001;

					// get the element that is a place holder for where we want to
					// draw the scene
					const element = scene.userData.element;

					// get its position relative to the page's viewport
					const rect = element.getBoundingClientRect();

					// check if it's offscreen. If so skip it
					if ( rect.bottom < 0 || rect.top > renderer.domElement.clientHeight ||
						 rect.right < 0 || rect.left > renderer.domElement.clientWidth ) {

						return; // it's off screen

					}

					// set the viewport
					const width = rect.right - rect.left;
					const height = rect.bottom - rect.top;
					const left = rect.left;
					const bottom = renderer.domElement.clientHeight - rect.bottom;

					renderer.setViewport( left, bottom, width, height );
					renderer.setScissor( left, bottom, width, height );

					const camera = scene.userData.camera;

					//camera.aspect = width / height; // not changing in this example
					//camera.updateProjectionMatrix();

					//scene.userData.controls.update();

					renderer.render( scene, camera );

				} );

			}
    }
})